package cn.buk.tms.bill.service;

import cn.buk.common.JsonResult;
import cn.buk.tms.dao.BillDao;
import cn.buk.tms.dao.FlightOrderDao;
import cn.buk.tms.sc.SearchBillInfoCriteria;
import cn.buk.qms.service.BaseAbstractService;
import cn.buk.tms.entity.base.Airline;
import cn.buk.tms.entity.bill.BillInfo;
import cn.buk.tms.entity.misc.Customer;
import cn.buk.tms.entity.misc.RoleInfo;
import cn.buk.tms.entity.order.flight.FlightOrder;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.access.annotation.Secured;
import org.springframework.stereotype.Service;

import java.util.List;

import static cn.buk.tms.common.constant.TmsOrderConstant.*;

@Service
public class BillCheckServiceImpl extends BaseAbstractService implements BillCheckService {

  private static final Logger logger = LogManager.getLogger(BillCheckServiceImpl.class);

  @Autowired
  private BillDao billDao;

  @Autowired
  private FlightOrderDao flightOrderDao;

  @Autowired
  private  BillImportService importService;

  /**
   * 检查账单的国际国内是否有值
   */
  @Override
  @Secured({RoleInfo.ROLE_ADMIN, RoleInfo.ROLE_CASHIER})
  public JsonResult checkBillIntlTicket(int enterpriseId) {
    return JsonResult.createJsonResult(billDao.checkBillIntlTicket(enterpriseId));
  }


  /**
   * 检查散客的、待结算账单对应的机票订单的收款情况
   */
  @Override
  @Secured({RoleInfo.ROLE_ADMIN, RoleInfo.ROLE_CASHIER})
  public JsonResult checkBillFlightOrderPayStatus(final int enterpriseId, final String username) {
    int count = 0;

    SearchBillInfoCriteria sc = new SearchBillInfoCriteria();
    sc.setPageSize(50000);
    sc.setBillType(BILL_TYPE_FLIGHT); // 机票账单
    sc.setBePaid("0");  // 未支付的
    sc.setReviewed(1); // 已审核的
    sc.setSettled(0); // 未结算的
    sc.setCustomerId(0); // 散客的

    List<BillInfo> billInfos = billDao.searchMyBillInfo(enterpriseId, sc);
    logger.info("(checkBillFlightOrderPayStatus) Bills size: {}", billInfos.size());
    for (BillInfo billInfo : billInfos) {
      FlightOrder flightOrder = flightOrderDao
              .getOrderDetailByOrderNo(enterpriseId, billInfo.getOrderNo());
      if (flightOrder.getPayStatus() == 1) {
        // 机票订单已收款，写备注到账单
        int retCode = billDao.updateBillInfoRemark(enterpriseId, username, billInfo.getId(),
                "订单(" + billInfo.getOrderNo() + ")已收款。");
        if (retCode > 0) {
          count++;
        }
      }
    }

    return JsonResult.createJsonResult(count, "更新了" + count + "账单的备注");
  }


  @Override
  public void autoCheckTrainBillPsgCount(String agentName) {
    billDao.updateTrainBillPsgCount(agentName);
  }


  @Override
  public void checkFlightOrderImportedStatus(final String agentName) {
    List<FlightOrder> flightOrders = flightOrderDao.searchUnImportedFlightOrders(10);

    for (FlightOrder flightOrder : flightOrders) {
      final int enterpriseId = flightOrder.getEnterpriseId();
      final int flightOrderId = flightOrder.getId();
      // 检查是否已导入过
      List<BillInfo> billInfos = billDao.searchBillInfos(enterpriseId, flightOrderId);
      if (!billInfos.isEmpty()) {
        // 已导入过，修改 billImported 状态
        int status = flightOrderDao
                .updateFlightOrderBillImported(enterpriseId, agentName, flightOrderId);
        if (status == 1) {
          logger.info("{}, {} bill imported : 1.", enterpriseId, flightOrderId);
        }
      } else {
        importService.importFlightOrder(enterpriseId, agentName, flightOrderId);
      }
    }
  }


  @Override
  public void checkBillSupplier(int enterpriseId, String username) {
    List<BillInfo> billInfos = billDao.searchSupplierIsNull(enterpriseId);
    if (!billInfos.isEmpty()) {
      logger.info("checkBillSupplier: {}", billInfos.size());
    }
    for (BillInfo o : billInfos) {
      if (o.getSupplier() != null || o.getPaymentMethod() != null) {
        continue;
      }

      var flightOrder = flightOrderDao.getOrderDetailByOrderNo(enterpriseId, o.getFlightOrderNo());
      if (flightOrder == null) {
        continue;
      }

      if (flightOrder.getSupplier() == null || flightOrder.getPaymentMethod() == null) {
        continue;
      }

      int retCode = billDao.updateBillSupplierAndPaymentMethod(enterpriseId, username, o.getId(), flightOrder.getSupplier(), flightOrder.getPaymentMethod());
      if (retCode > 0) {
        String content = username + " 更新账单(" + o.getBillNum() + ")供应商为 "
                + flightOrder.getSupplier().getName() + ", " +
                "支出方式为 " + flightOrder.getPaymentMethod().getName();
        doSendAlert(enterpriseId, content, "Dai", 0);
      }

    }
  }


  @Override
  public void syncBillAirlines() {
    List<Airline> airlines = basicDataDao.getAllAirlines();

    final int max = 50000;
    List<BillInfo> bills = billDao.searchBillByAirlinesIsNull(BILL_TYPE_FLIGHT, max);
    execUpdateBillCarrier(bills, airlines);

    bills = billDao.searchBillByAirlinesIsNull(BILL_TYPE_FLIGHT_REFUND, max);
    execUpdateBillCarrier(bills, airlines);

    bills = billDao.searchBillByAirlinesIsNull(BILL_TYPE_FLIGHT_CHANGE, max);
    execUpdateBillCarrier(bills, airlines);
  }


  /**
   * 将账单中carrier属性填充
   *
   */
  private void execUpdateBillCarrier(List<BillInfo> bills, List<Airline> airlines) {
    for (BillInfo bill : bills) {
      BillInfo billInfo = billDao.getBillInfo(bill.getId(), true);

      String twoCode = null;

      if (BILL_TYPE_FLIGHT.equalsIgnoreCase(bill.getBillType())) {
        if (billInfo.getTickets().isEmpty()) {
          continue;
        }

        final String threeCode = billInfo.getTickets().get(0).getBalanceCode();

        twoCode = convertTwoCode2ThreeCode(threeCode, airlines);
      } else if (BILL_TYPE_FLIGHT_REFUND.equalsIgnoreCase(bill.getBillType())) {
        if (billInfo.getRefundTickets().isEmpty()) {
          continue;
        }

        final String threeCode = billInfo.getRefundTickets().get(0).getBalanceCode();

        twoCode = convertTwoCode2ThreeCode(threeCode, airlines);
      } else if (BILL_TYPE_FLIGHT_CHANGE.equalsIgnoreCase(bill.getBillType())) {
        if (billInfo.getChangeOrders().isEmpty()) {
          continue;
        }

        final String threeCode = billInfo.getChangeOrders().get(0).getBalanceCode();

        twoCode = convertTwoCode2ThreeCode(threeCode, airlines);
      }

      if (twoCode == null) {
        continue;
      }

      billDao.updateBillInfoAirlines(bill.getId(), twoCode);
    }
  }


  private String convertTwoCode2ThreeCode(String threeCode, List<Airline> airlines) {
    for (Airline airline : airlines) {
      if (airline.getThreeCode().equalsIgnoreCase(threeCode)) {
        return airline.getTwoCode();
      }
    }

    return null;
  }


  /**
   * 将账单中的金额同步到现金账户中
   */
  @Override
  public void syncBillInfo2Balance() {
    List<BillInfo> bills = billDao.searchBillInfoNotProcessed(5000);

    for (BillInfo bill : bills) {
      //散客订单不处理
      if (bill.getCustomerType() == Customer.ENT_INDIVIDUAL) {
        continue;
      }

      final int enterpriseId = bill.getEnterpriseId();
      final int customerEntId = bill.getCustomer().getCustomerEnterpriseId();
      if (customerEntId > 0) {
        int billSum = (int) (bill.getBillSum() * 100);
        billDao.syncBillInfo2Balance(enterpriseId, customerEntId, bill.getId(), bill.getBillNum(), billSum);
      }
    }
  }


}
